package com.wonders.config;


import net.sf.ehcache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;

@EnableCaching
@Configuration
public class CacheConfig2 {


    /**
     * 1、引入配置
     * <dependency>
     * <groupId>net.sf.ehcache</groupId>
     * <artifactId>ehcache</artifactId>
     * </dependency>
     * 2、application.yml中指定缓存类型和ehcache配置文件位置
     * spring:
     *   cache:
     *     type: ehcache
     *     ehcache:
     *       config: classpath:ehcache.xml
     * 3、classpath下创建ehcache的配置文件并配置
     * 4、创建CacheManager
     * 5、使用
     *
     * @return
     */
    @Bean
    public EhCacheCacheManager cacheManager() {
        // CacheManager
        EhCacheCacheManager ehCacheCacheManager = new EhCacheCacheManager();
        return ehCacheCacheManager;
    }

    @PostConstruct
    private void init() {
        /**
         * 开启该属性，Ehcache会为每一个创建的EhCacheCacheManager注册一
         * 个回调钩子（详见：net.sf.ehcache.CacheManager#addShutdownHookIfRequired）。
         * 该钩子将在"应用程序"关闭时被调用，该钩子的作用就是关闭创建的EhCacheCacheManager。
         */
        System.setProperty(CacheManager.ENABLE_SHUTDOWN_HOOK_PROPERTY, "true");
        // 当EhCacheCacheManager被关闭时，内存中的数据将被刷新到磁盘。
        // 使用钩子的好处就是即使你不是在一个web环境内，也同样可以将内存缓存数据序列化到磁盘
    }

    /**
     * 配置ShutdownListener，当tomcat正常关闭时，所有的EhCacheCacheManager实例都将关闭，在关闭前内存中缓存的数据将被刷新到磁盘。
     * 注意此Listener在测试代码中不会起作用，因为测试代码不会启动Tomcat，只会启动容器。
     * @return
     */
//    @Bean
//    public ServletListenerRegistrationBean<ShutdownListener> shutdownListener() {
//        ServletListenerRegistrationBean<ShutdownListener> listenerRegistrationBean = new ServletListenerRegistrationBean<>();
//        listenerRegistrationBean.setListener(new ShutdownListener());
//        return listenerRegistrationBean;
//    }

    // JVM关闭方式：http://www.wjhsh.net/waterystone-p-12884761.html
    // 如何优雅的让一个程序退出：https://www.51cto.com/article/672263.html
    // kill -9和kill -15的区别：https://blog.csdn.net/chuixue24/article/details/107689316
    // springboot的actuator的优雅关闭是如何实现的？http://t.zoukankan.com/duanxz-p-11302110.html

    /**
     * 如果只有一个EhCacheCacheManager实例需要在tomcat关闭时关闭，可配置如下
     */
//    @PreDestroy
//    private void destroy() {
////        // 关闭tomcat时，执行相应的关闭
//        CacheManager.getInstance().shutdown();
//    }
}
